package group

// Context 上下文实现
// 编程规范
//  错误的使用调度库可能会导致极端情况下的调度锁死
//  上下文接口 规范了在使用调度 接口 的时候的超时
//  业务代码自行退出的实现方法,但只是一种对业务代
//  码的错误起到预防作用并不能完全消除可能存在的错误
type Context interface {
	Conn
	// 业务代码
	Go(fn func(conn Context) error) // 用户业务
	Done() <-chan struct{}          // 业务中断
	// 调度代码
	Run(conn Conn) error // 调度调用 Group.Go(Context.Run)
	Close() error        // 通知业务结束
}

// 上下文实现
type context struct {
	Conn
	fn   func(conn Context) error
	done chan struct{}
}

func (c *context) Go(fn func(conn Context) error) {
	c.fn = fn
}
func (c *context) Done() <-chan struct{} {
	return c.done
}
func (c *context) Run(conn Conn) (err error) {
	c.Conn = conn
	// 调用
	err = c.fn(c)
	// 关闭
	c.Close()
	return err
}
func (c *context) Close() error {
Set:
	select {
	case c.done <- struct{}{}:
		goto Set
	default:
	}
	return nil
}

// NewContext 创建上下文
func NewContext() Context {
	return &context{done: make(chan struct{})}
}
